package com.yanqu.road.message;

import com.google.protobuf.Message;
import com.yanqu.road.define.YanQuMessageDefine;
import io.netty.buffer.ByteBuf;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.Serializable;

public class YanQuMessage implements Serializable, Cloneable {
	private static Logger logger = LogManager.getLogger(YanQuMessage.class.getName());
	private static final long serialVersionUID = 1L;
	private short header = YanQuMessageDefine.HEADER_MARK;
	private int len;
	private int code;
	private long playerId;

	private int msgDataLength;
	private byte[] bytes;

	private Message message;

	private byte opCode = YanQuMessageDefine.OP_CODE;
	private Object myMsg;

	public YanQuMessage() {

	}

	public YanQuMessage(Object myMsg) {
		this.myMsg = myMsg;
	}

	public YanQuMessage(int code, byte[] bytes) {
		this(code, -1);
		this.bytes = bytes;
	}

	public YanQuMessage(int code) {
		this(code, -1);
	}

	public YanQuMessage(int code, long playerId) {
		this.code = code;
		this.playerId = playerId;
	}

	public YanQuMessage(int code, Object myMsg) {
		this.code = code;
		this.myMsg = myMsg;
	}

	public YanQuMessage(int code, int playerId, Object myMsg) {
		this.code = code;
		this.playerId = playerId;
		this.myMsg = myMsg;
	}

	public short getHeader() {
		return header;
	}

	public int getLen() {
		return len;
	}

	public void setLen(int len) {
		this.len = len;
	}

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public long getPlayerId() {
		return playerId;
	}

	public void setPlayerId(long playerId) {
		this.playerId = playerId;
	}

	public byte[] getBytes() {
		return bytes;
	}

	public void setBytes(byte[] bytes) {
		this.bytes = bytes;
	}

	public Message getMessage() {
		return message;
	}

	public void setMessage(Message message) {
		this.message = message;
	}

	public void readHeaderNetty(ByteBuf in) {
		in.readShort();
		len = in.readInt();
		code = in.readInt();
		playerId = in.readLong();
	}


	public void read(ByteBuf in) {
		in.readShort();
		len = in.readInt();
		code = in.readInt();
		playerId = in.readLong();

		bytes = new byte[in.capacity() - YanQuMessageDefine.HEADER_SIZE];
		in.readBytes(bytes);
	}

	@Override
	public YanQuMessage clone() {
		YanQuMessage clone = null;
		try {
			clone = (YanQuMessage) super.clone();
			clone.setMessage(message);
			return clone;
		} catch (CloneNotSupportedException e) {
			logger.error("异常错误", e);
			return null;
		}
	}

	@Override
	public String toString() {
		return msgHeaderStr();
	}

	public void writeHeader(int len, ByteBuf out) {
		out.writeShort(YanQuMessageDefine.HEADER_MARK);
		out.writeInt(len);
		out.writeInt(code);
		out.writeLong(playerId);
		if (message != null) {
			out.writeBytes(message.toByteArray());
		} else if (bytes != null) {
			if (msgDataLength != 0) {
				out.writeBytes(bytes, 0, msgDataLength);
			} else {
				out.writeBytes(bytes);
			}
		}
	}

	public void writeHeaderByte(int len, ByteBuf out) {
		out.writeShort(YanQuMessageDefine.HEADER_MARK);
		out.writeInt(len);
		out.writeInt(code);
		out.writeLong(playerId);
		if (bytes != null) {
			out.writeBytes(bytes);
		}
	}

	public byte[] toByteArray() {
		return bytes;
	}

	public String msgHeaderStr() {
		StringBuilder sb = new StringBuilder();
		sb.append("playerId : ").append(playerId);
		sb.append(", code : ").append(Integer.toHexString(code));
		sb.append(", len : ").append(len);
		return sb.toString();
	}


	public byte getOpCode() {
		return opCode;
	}

	public Object getMyMsg() {
		return myMsg;
	}


	public void setMsgDataLength(int msgDataLength) {
		this.msgDataLength = msgDataLength;
	}

	public int getMsgDataLength() {
		return this.msgDataLength;
	}

}
